﻿using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;

namespace HPSocketLibrary
{

    /// <summary>
    /// 由Object取值
    /// </summary>
    public static class ConvertHelepr
    {
        public static UInt32 FloatToUint(this float x)
        {
            byte[] bytes = BitConverter.GetBytes(x);
            return BitConverter.ToUInt32(bytes, 0);
        }
        public static float UintToFloat(this UInt32 x)
        {
            byte[] bytes = BitConverter.GetBytes(x);
            return BitConverter.ToSingle(bytes, 0);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="thisValue"></param>
        /// <returns></returns>
        public static string ObjToString(this object thisValue)
        {
            if (thisValue != null) return thisValue.ToString().Trim();
            return "";
        }
        /// <summary>
        /// 取得Int16值
        /// </summary>
        public static Int16 ToInt16(this object obj, Int16 value = 0)
        {
            if (obj != null && obj != DBNull.Value && obj.ToString() != "NaN")
            {
                short result;
                if (Int16.TryParse(obj.ToString(), out result))
                    return result;
                else
                    return value;
            }
            else
            {
                return value;
            }
        }
        /// <summary>
        /// 取得Int32值
        /// </summary>
        public static Int32 ToInt32(this object obj, Int32 value = 0)
        {
            if (obj != null && obj != DBNull.Value && obj.ToString() != "NaN")
            {
                int result;
                if (Int32.TryParse(obj.ToString(), out result))
                    return result;
                else
                    return value;
            }
            else
            {
                return value;
            }
        }

        /// <summary>
        /// 取得UInt16值
        /// </summary>
        public static UInt16 ToUInt16(this object obj, UInt16 value = 0)
        {
            if (obj != null && obj != DBNull.Value && obj.ToString() != "NaN")
            {
                ushort result;
                if (UInt16.TryParse(obj.ToString(), out result))
                    return result;
                else
                    return value;
            }
            else
            {
                return value;
            }
        }
        /// <summary>
        /// 取得UInt32值
        /// </summary>
        public static UInt32 ToUInt32(this object obj, UInt32 value = 0)
        {
            if (obj != null && obj != DBNull.Value && obj.ToString() != "NaN")
            {
                UInt32 result;
                if (UInt32.TryParse(obj.ToString(), out result))
                    return result;
                else
                    return value;
            }
            else
            {
                return value;
            }
        }

        /// <summary>
        /// 取得Int值
        /// </summary>
        public static int ToInt(this object obj, int value = 0)
        {
            if (obj != null && obj != DBNull.Value)
            {
                int result;
                if (int.TryParse(obj.ToString(), out result))
                    return result;
                else
                    return value;
            }
            else
            {
                return value;
            }
        }

        /// <summary>
        /// 取得UInt值
        /// </summary>
        public static uint ToUInt(this object obj, uint value = 0)
        {
            if (obj != null && obj != DBNull.Value)
            {
                uint result;
                if (uint.TryParse(obj.ToString(), out result))
                    return result;
                else
                    return value;
            }
            else
            {
                return value;
            }
        }

        /// <summary>
        /// 取得UInt64值
        /// </summary>
        public static ulong ToULong(this object obj, ulong value = 0)
        {
            if (obj != null && obj != DBNull.Value)
            {
                ulong result;
                if (ulong.TryParse(obj.ToString(), out result))
                    return result;
                else
                    return value;
            }
            else
            {
                return value;
            }
        }

        /// <summary>
        /// 取得byte值
        /// </summary>
        public static byte ToByte(this object obj)
        {
            if (obj != null && obj != DBNull.Value)
            {
                byte result;
                if (byte.TryParse(obj.ToString(), out result))
                    return result;
                else
                    return 0;
            }
            else
            {
                return 0;
            }
        }

        /// <summary>
        /// 取得sbyte值
        /// </summary>
        public static sbyte ToSByte(this object obj)
        {
            if (obj != null && obj != DBNull.Value)
            {
                sbyte result;
                if (sbyte.TryParse(obj.ToString(), out result))
                    return result;
                else
                    return 0;
            }
            else
            {
                return 0;
            }
        }

        /// <summary>
        /// 获得Long值
        /// </summary>
        public static long ToLong(this object obj, long value = 0)
        {
            if (obj != null && obj != DBNull.Value)
            {
                long result;
                if (long.TryParse(obj.ToString(), out result))
                    return result;
                else
                    return value;
            }
            else
            {
                return value;
            }
        }

        /// <summary>
        /// 取得Decimal值
        /// </summary>
        public static decimal ToDecimal(this object obj, decimal value = 0)
        {
            if (obj != null && obj != DBNull.Value)
            {
                decimal result;
                if (decimal.TryParse(obj.ToString(), out result))
                    return result;
                else
                    return value;
            }
            else
            {
                return value;
            }
        }

        /// <summary>
        /// 取得float值
        /// </summary>
        public static float ToFloat(this object obj, float value = 0)
        {
            if (obj != null && obj != DBNull.Value)
            {
                float result;
                if (float.TryParse(obj.ToString(), out result))
                    return result;
                else
                    return value;
            }
            else
            {
                return value;
            }
        }

        /// <summary>
        /// 取得double值
        /// </summary>
        public static double ToDouble(this object obj, double value = 0)
        {
            if (obj != null && obj != DBNull.Value && obj.ToString() != "NaN")
            {
                double result;
                if (double.TryParse(obj.ToString(), out result))
                    return result;
                else
                    return value;
            }
            else
            {
                return value;
            }
        }

        /// <summary>
        /// 取得Guid值
        /// </summary>
        public static Guid? ToGuid(this object obj)
        {
            if (obj != null && obj != DBNull.Value)
            {
                try
                {
                    Guid result = new Guid(obj.ToString());
                    return result;
                }
                catch
                {
                    return null;
                }
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 取得DateTime值
        /// </summary>
        public static DateTime ToDateTime(this object obj)
        {
            if (obj != null && obj != DBNull.Value)
            {
                DateTime result;
                if (DateTime.TryParse(obj.ToString(), out result))
                    return result;
                else
                    return DateTime.Now;
            }
            else
            {
                return DateTime.Now;
            }
        }
        public static string ToStringDay(this object source) { 
        
            return source.ToDateTime().ToString("yyyy-MM-dd");
        }
        public static string ToStringDateTime(this object source) { 
        
            return source.ToDateTime().ToString("yyyy-MM-dd HH:mm:ss");
        }
        /// <summary>
        /// 取得bool值
        /// </summary>
        public static bool ToBool(this object obj, bool value = false)
        {
            if (obj != null && obj != DBNull.Value)
            {
                try
                {

                    bool.TryParse(obj.ToString().ToLower(), out value);
                }
                catch
                {

                }
            }
            return value;
        }
        /// <summary>
        /// 取得bool值
        /// </summary>
        public static bool ToBool(this object obj)
        {
            return ToBool(obj,false);
        }

        /// <summary>
        /// 取得byte[]
        /// </summary>
        public static byte[] ToBinary(this object obj)
        {
            if (obj != null && obj != DBNull.Value)
            {
                return (byte[])obj;
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 取得string值
        /// </summary>
        public static string ToString(this object obj,string value = "")
        {
            if (obj != null && obj != DBNull.Value)
            {
                return obj.ToString();
            }
            else
            {
                return value;
            }
        }
        /// <summary>
        /// 字符串转换为指定格式的列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value">字符串内容</param>
        /// <param name="delimiter">分隔符号</param>
        /// <returns></returns>
        public static List<T> ToDelimitedList<T>(this string value, string delimiter)
        {
            if (value == null)
            {
                return new List<T>();
            }

            var output = value.Split(new string[] { delimiter }, StringSplitOptions.RemoveEmptyEntries);
            return output.Select(x => (T)Convert.ChangeType(x, typeof(T))).ToList();
        }

        /// <summary>
        /// 字符串转换为指定格式的列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value">字符串内容</param>
        /// <param name="delimiter">分隔符号</param>
        /// <param name="converter">提供的转换操作</param>
        /// <returns></returns>
        public static List<T> ToDelimitedList<T>(this string value, string delimiter, Func<string, T> converter)
        {
            if (value == null)
            {
                return new List<T>();
            }

            var output = value.Split(new string[] { delimiter }, StringSplitOptions.RemoveEmptyEntries);
            return output.Select(converter).ToList();
        }
        /// <summary>
        /// 根据长度分割不同的字符串到列表里面
        /// </summary>
        /// <param name="value">字符串内容</param>
        /// <param name="length">分割的长度</param>
        /// <returns></returns>
        public static IEnumerable<string> SplitEvery(this string value, int length)
        {
            int index = 0;
            while (index + length < value.Length)
            {
                yield return value.Substring(index, length);
                index += length;
            }

            if (index < value.Length)
                yield return value.Substring(index, value.Length - index);
        }

        /// <summary>
        /// 整型格式化为货币型
        /// </summary>
        /// <param name="convert">需格式化字符串</param>
        /// <returns></returns>
        public static string ToMoney(this object convert)
        {
            try
            {
                return String.Format("{0:N2}", Convert.ToDecimal(convert.ToString().Replace("￥", "")));
            }
            catch (Exception) { }
            return "0.00";
        }
        public static object? ToJson(this string Json)
        {
            return Json == null ? null : JsonConvert.DeserializeObject(Json);
        }
        public static string ToJson(this object obj)
        {
            var timeConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" };
            return JsonConvert.SerializeObject(obj, timeConverter);
        }
        public static string ToJson(this object obj, string datetimeformats)
        {
            var timeConverter = new IsoDateTimeConverter { DateTimeFormat = datetimeformats };
            return JsonConvert.SerializeObject(obj, timeConverter);
        }
        public static T? ToObject<T>(this object? Json)
        {
            return Json == null ? default(T) : JsonConvert.DeserializeObject<T>(Json.ObjToString());
        }
        public static List<T>? ToList<T>(this string Json)
        {
            return Json == null ? null : JsonConvert.DeserializeObject<List<T>>(Json);
        }
        public static DataTable? ToTable(this string Json)
        {
            return Json == null ? null : JsonConvert.DeserializeObject<DataTable>(Json);
        }
        public static JObject ToJObject(this string Json)
        {
            return Json == null || !Json.Contains("{\"") ? JObject.Parse("{}") : JObject.Parse(Json.Replace("&nbsp;", ""));
        }
        public static JArray ToJArray(this string Json)
        {
            return Json == null || !Json.Contains("{\"") ? JArray.Parse("{}") : JArray.Parse(Json.Replace("&nbsp;", ""));
        }
        /// <summary>
        /// 将object对象转换为实体对象
        /// </summary>
        /// <typeparam name="T">实体对象类名</typeparam>
        /// <param name="asObject">object对象</param>
        /// <returns></returns>
        public static T ToEntity<T>(this object asObject) where T : new()
        {
            //创建实体对象实例
            var t = Activator.CreateInstance<T>();
            if (asObject != null)
            {
                JObject type = asObject.ToJson().ToJObject();
                //遍历实体对象属性
                foreach (var info in typeof(T).GetProperties())
                {
                    object obj = null;
                    //取得object对象中此属性的值
                    var val = type.Value<object>(info.Name);
                    if (val != null)
                    {
                        //非泛型
                        if (!info.PropertyType.IsGenericType)
                            obj = Convert.ChangeType(val, info.PropertyType);
                        else//泛型Nullable<>
                        {
                            Type genericTypeDefinition = info.PropertyType.GetGenericTypeDefinition();
                            if (genericTypeDefinition == typeof(Nullable<>))
                            {
                                obj = Convert.ChangeType(val, Nullable.GetUnderlyingType(info.PropertyType));
                            }
                            else
                            {
                                obj = Convert.ChangeType(val, info.PropertyType);
                            }
                        }
                        info.SetValue(t, obj, null);
                    }
                }
            }
            return t;
        }

        public static void Swap<T>(this IList<T> list, int indexA, int indexB)
        {
            T temp = list[indexA];
            list[indexA] = list[indexB];
            list[indexB] = temp;
        }
        public static bool IsNotEmptyOrNull(this object thisValue)
        {
            return thisValue.ObjToString() != "" && thisValue.ObjToString() != "undefined" && thisValue.ObjToString() != "null";
        }
    }
}
